home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / gcc263-src.lha / gcc-2.6.3 / cp / xref.c < prev   
C/C++ Source or Header  |  1994-06-15  |  18KB  |  840 lines

  1. /* Code for handling XREF output from GNU C++.
  2.    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
  3.    Contributed by Michael Tiemann (tiemann@cygnus.com)
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21.  
  22. #include "config.h"
  23. #include "tree.h"
  24. #include <stdio.h>
  25. #include "cp-tree.h"
  26. #include "input.h"
  27.  
  28. #include <ctype.h>
  29.  
  30. extern char *getpwd ();
  31.  
  32. extern char *index ();
  33. extern char *rindex ();
  34.  
  35. /* The character(s) used to join a directory specification (obtained with
  36.    getwd or equivalent) with a non-absolute file name.  */
  37.  
  38. #ifndef FILE_NAME_JOINER
  39. #define FILE_NAME_JOINER "/"
  40. #endif
  41.  
  42. /* Nonzero if NAME as a file name is absolute.  */
  43. #ifndef FILE_NAME_ABSOLUTE_P
  44. #define FILE_NAME_ABSOLUTE_P(NAME) (NAME[0] == '/')
  45. #endif
  46.  
  47. /* For cross referencing.  */
  48.  
  49. int flag_gnu_xref;
  50.  
  51. /************************************************************************/
  52. /*                                    */
  53. /*    Common definitions                        */
  54. /*                                    */
  55. /************************************************************************/
  56.  
  57. #ifndef TRUE
  58. #define TRUE 1
  59. #endif
  60. #ifndef FALSE
  61. #define FALSE 0
  62. #endif
  63. #ifndef NULL
  64. #define NULL 0
  65. #endif
  66.  
  67. #define PALLOC(typ) ((typ *) calloc(1,sizeof(typ)))
  68.  
  69.  
  70. /* Return a malloc'd copy of STR.  */
  71. #define SALLOC(str) \
  72.  ((char *) ((str) == NULL ? NULL    \
  73.         : (char *) strcpy ((char *) malloc (strlen ((str)) + 1), (str))))
  74. #define SFREE(str) (str != NULL && (free(str),0))
  75.  
  76. #define STREQL(s1,s2) (strcmp((s1),(s2)) == 0)
  77. #define STRNEQ(s1,s2) (strcmp((s1),(s2)) != 0)
  78. #define STRLSS(s1,s2) (strcmp((s1),(s2)) < 0)
  79. #define STRLEQ(s1,s2) (strcmp((s1),(s2)) <= 0)
  80. #define STRGTR(s1,s2) (strcmp((s1),(s2)) > 0)
  81. #define STRGEQ(s1,s2) (strcmp((s1),(s2)) >= 0)
  82.  
  83. /************************************************************************/
  84. /*                                    */
  85. /*    Type definitions                        */
  86. /*                                    */
  87. /************************************************************************/
  88.  
  89.  
  90. typedef struct _XREF_FILE *    XREF_FILE;
  91. typedef struct _XREF_SCOPE *    XREF_SCOPE;
  92.  
  93. typedef struct _XREF_FILE
  94. {
  95.   char *name;
  96.   char *outname;
  97.   XREF_FILE next;
  98. } XREF_FILE_INFO;
  99.  
  100. typedef struct _XREF_SCOPE
  101. {
  102.   int gid;
  103.   int lid;
  104.   XREF_FILE file;
  105.   int start;
  106.   XREF_SCOPE outer;
  107. } XREF_SCOPE_INFO;
  108.  
  109. /************************************************************************/
  110. /*                                    */
  111. /*    Local storage                            */
  112. /*                                    */
  113. /************************************************************************/
  114.  
  115. static    char        doing_xref = 0;
  116. static    FILE *        xref_file = NULL;
  117. static    char        xref_name[1024];
  118. static    XREF_FILE    all_files = NULL;
  119. static    char *        wd_name = NULL;
  120. static    XREF_SCOPE    cur_scope = NULL;
  121. static    int     scope_ctr = 0;
  122. static    XREF_FILE    last_file = NULL;
  123. static    tree        last_fndecl = NULL;
  124.  
  125. /************************************************************************/
  126. /*                                    */
  127. /*    Forward definitions                        */
  128. /*                                    */
  129. /************************************************************************/
  130.  
  131. extern    void        GNU_xref_begin();
  132. extern    void        GNU_xref_end();
  133. extern    void        GNU_xref_file();
  134. extern    void        GNU_xref_start_scope();
  135. extern    void        GNU_xref_end_scope();
  136. extern    void        GNU_xref_ref();
  137. extern    void        GNU_xref_decl();
  138. extern    void        GNU_xref_call();
  139. extern    void        GNU_xref_function();
  140. extern    void        GNU_xref_assign();
  141. extern    void        GNU_xref_hier();
  142. extern    void        GNU_xref_member();
  143.  
  144. static    void        gen_assign();
  145. static    XREF_FILE    find_file();
  146. static    char *        filename();
  147. static    char *        fctname();
  148. static    char *        declname();
  149. static    void        simplify_type();
  150. static    char *        fixname();
  151. static    void        open_xref_file();
  152.  
  153. extern    char *        type_as_string();
  154.  
  155. /* Start cross referencing.  FILE is the name of the file we xref.  */
  156.  
  157. void
  158. GNU_xref_begin (file)
  159.    char *file;
  160. {
  161.   doing_xref = 1;
  162.  
  163.   if (file != NULL && STRNEQ (file,"-"))
  164.     {
  165.       open_xref_file(file);
  166.       GNU_xref_file(file);
  167.     }
  168. }
  169.  
  170. /* Finish cross-referencing.  ERRCNT is the number of errors
  171.    we encountered.  */
  172.  
  173. void
  174. GNU_xref_end (ect)
  175.    int ect;
  176. {
  177.   XREF_FILE xf;
  178.  
  179.   if (!doing_xref) return;
  180.  
  181.   xf = find_file (input_filename);
  182.   if (xf == NULL) return;
  183.  
  184.   while (cur_scope != NULL)
  185.     GNU_xref_end_scope(cur_scope->gid,0,0,0,0);
  186.  
  187.   doing_xref = 0;
  188.  
  189.   if (xref_file == NULL) return;
  190.  
  191.   fclose (xref_file);
  192.  
  193.   xref_file = NULL;
  194.   all_files = NULL;
  195.  
  196.   if (ect > 0) unlink (xref_name);
  197. }
  198.  
  199. /* Write out xref for file named NAME.  */
  200.  
  201. void
  202. GNU_xref_file (name)
  203.    char *name;
  204. {
  205.   XREF_FILE xf;
  206.  
  207.   if (!doing_xref || name == NULL) return;
  208.  
  209.   if (xref_file == NULL)
  210.     {
  211.       open_xref_file (name);
  212.       if (!doing_xref) return;
  213.     }
  214.  
  215.   if (all_files == NULL)
  216.     fprintf(xref_file,"SCP * 0 0 0 0 RESET\n");
  217.  
  218.   xf = find_file (name);
  219.   if (xf != NULL) return;
  220.  
  221.   xf = PALLOC (XREF_FILE_INFO);
  222.   xf->name = SALLOC (name);
  223.   xf->next = all_files;
  224.   all_files = xf;
  225.  
  226.   if (wd_name == NULL)
  227.     wd_name = getpwd ();
  228.  
  229.   if (FILE_NAME_ABSOLUTE_P (name) || ! wd_name)
  230.     xf->outname = xf->name;
  231.   else
  232.     {
  233.       char *nmbuf
  234.     = (char *) malloc (strlen (wd_name) + strlen (FILE_NAME_JOINER)
  235.                + strlen (name) + 1);
  236.       sprintf (nmbuf, "%s%s%s", wd_name, FILE_NAME_JOINER, name);
  237.       name = nmbuf;
  238.       xf->outname = nmbuf;
  239.     }
  240.  
  241.   fprintf (xref_file, "FIL %s %s 0\n", name, wd_name);
  242.  
  243.   filename (xf);
  244.   fctname (NULL);
  245. }
  246.  
  247. /* Start a scope identified at level ID.  */
  248.  
  249. void
  250. GNU_xref_start_scope (id)
  251.    HOST_WIDE_INT id;
  252. {
  253.   XREF_SCOPE xs;
  254.   XREF_FILE xf;
  255.  
  256.   if (!doing_xref) return;
  257.   xf = find_file (input_filename);
  258.  
  259.   xs = PALLOC (XREF_SCOPE_INFO);
  260.   xs->file = xf;
  261.   xs->start = lineno;
  262.   if (xs->start <= 0) xs->start = 1;
  263.   xs->gid = id;
  264.   xs->lid = ++scope_ctr;
  265.   xs->outer = cur_scope;
  266.   cur_scope = xs;
  267. }
  268.  
  269. /* Finish a scope at level ID.
  270.    INID is ???
  271.    PRM is ???
  272.    KEEP is nonzero iff this scope is retained (nonzero if it's
  273.    a compiler-generated invisible scope).
  274.    TRNS is ???  */
  275.  
  276. void
  277. GNU_xref_end_scope (id,inid,prm,keep,trns)
  278.    HOST_WIDE_INT id;
  279.    HOST_WIDE_INT inid;
  280.    int prm,keep,trns;
  281. {
  282.   XREF_FILE xf;
  283.   XREF_SCOPE xs,lxs,oxs;
  284.   char *stype;
  285.  
  286.   if (!doing_xref) return;
  287.   xf = find_file (input_filename);
  288.   if (xf == NULL) return;
  289.  
  290.   lxs = NULL;
  291.   for (xs = cur_scope; xs != NULL; xs = xs->outer)
  292.     {
  293.       if (xs->gid == id) break;
  294.       lxs = xs;
  295.     }
  296.   if (xs == NULL) return;
  297.  
  298.   if (inid != 0) {
  299.     for (oxs = cur_scope; oxs != NULL; oxs = oxs->outer) {
  300.       if (oxs->gid == inid) break;
  301.     }
  302.     if (oxs == NULL) return;
  303.     inid = oxs->lid;
  304.   }
  305.  
  306.   if (prm == 2) stype = "SUE";
  307.   else if (prm != 0) stype = "ARGS";
  308.   else if (keep == 2 || inid != 0) stype = "INTERN";
  309.   else stype = "EXTERN";
  310.  
  311.   fprintf (xref_file,"SCP %s %d %d %d %d %s\n",
  312.        filename (xf), xs->start, lineno,xs->lid, inid, stype);
  313.  
  314.   if (lxs == NULL) cur_scope = xs->outer;
  315.   else lxs->outer = xs->outer;
  316.  
  317.   free (xs);
  318. }
  319.  
  320. /* Output a reference to NAME in FNDECL.  */
  321.  
  322. void
  323. GNU_xref_ref (fndecl,name)
  324.    tree fndecl;
  325.    char *name;
  326. {
  327.   XREF_FILE xf;
  328.  
  329.   if (!doing_xref) return;
  330.   xf = find_file (input_filename);
  331.   if (xf == NULL) return;
  332.  
  333.   fprintf (xref_file, "REF %s %d %s %s\n",
  334.        filename (xf), lineno, fctname (fndecl), name);
  335. }
  336.  
  337. /* Output a reference to DECL in FNDECL.  */
  338.  
  339. void
  340. GNU_xref_decl (fndecl,decl)
  341.    tree fndecl;
  342.    tree decl;
  343. {
  344.   XREF_FILE xf,xf1;
  345.   char *cls;
  346.   char *name;
  347.   char buf[10240];
  348.   int uselin;
  349.  
  350.   if (!doing_xref) return;
  351.   xf = find_file (input_filename);
  352.   if (xf == NULL) return;
  353.  
  354.   uselin = FALSE;
  355.  
  356.   if (TREE_CODE (decl) == TYPE_DECL) cls = "TYPEDEF";
  357.   else if (TREE_CODE (decl) == FIELD_DECL) cls = "FIELD";
  358.   else if (TREE_CODE (decl) == VAR_DECL)
  359.     {
  360.       if (fndecl == NULL && TREE_STATIC(decl)
  361.       && TREE_READONLY(decl) && DECL_INITIAL(decl) != 0
  362.       && !TREE_PUBLIC(decl) && !DECL_EXTERNAL(decl)
  363.       && DECL_MODE(decl) != BLKmode) cls = "CONST";
  364.       else if (DECL_EXTERNAL(decl)) cls = "EXTERN";
  365.       else if (TREE_PUBLIC(decl)) cls = "EXTDEF";
  366.       else if (TREE_STATIC(decl)) cls = "STATIC";
  367.       else if (DECL_REGISTER(decl)) cls = "REGISTER";
  368.       else cls = "AUTO";
  369.     }
  370.   else if (TREE_CODE (decl) == PARM_DECL) cls = "PARAM";
  371.   else if (TREE_CODE (decl) == FIELD_DECL) cls = "FIELD";
  372.   else if (TREE_CODE (decl) == CONST_DECL) cls = "CONST";
  373.   else if (TREE_CODE (decl) == FUNCTION_DECL)
  374.     {
  375.       if (DECL_EXTERNAL (decl)) cls = "EXTERN";
  376.       else if (TREE_PUBLIC (decl)) cls = "EFUNCTION";
  377.       else cls = "SFUNCTION";
  378.     }
  379.   else if (TREE_CODE (decl) == LABEL_DECL) cls = "LABEL";
  380.   else if (TREE_CODE (decl) == UNION_TYPE)
  381.     {
  382.       cls = "UNIONID";
  383.       decl = TYPE_NAME (decl);
  384.       uselin = TRUE;
  385.     }
  386.   else if (TREE_CODE (decl) == RECORD_TYPE)
  387.     {
  388.       if (CLASSTYPE_DECLARED_CLASS (decl)) cls = "CLASSID";
  389.       else if (IS_SIGNATURE (decl)) cls = "SIGNATUREID";
  390.       else cls = "STRUCTID";
  391.       decl = TYPE_NAME (decl);
  392.       uselin = TRUE;
  393.     }
  394.   else if (TREE_CODE (decl) == ENUMERAL_TYPE)
  395.     {
  396.       cls = "ENUMID";
  397.       decl = TYPE_NAME (decl);
  398.       uselin = TRUE;
  399.     }
  400.   else if (TREE_CODE (decl) == TEMPLATE_DECL)
  401.     {
  402.       if (DECL_TEMPLATE_IS_CLASS (decl))
  403.     cls = "CLASSTEMP";
  404.       else if (TREE_CODE (DECL_RESULT (decl)) == FUNCTION_DECL)
  405.     cls = "FUNCTEMP";
  406.       else if (TREE_CODE (DECL_RESULT (decl)) == VAR_DECL)
  407.     cls = "VARTEMP";
  408.       else
  409.     my_friendly_abort (358);
  410.       uselin = TRUE;
  411.     }
  412.   else cls = "UNKNOWN";
  413.  
  414.   if (decl == NULL || DECL_NAME (decl) == NULL) return;
  415.  
  416.   if (uselin && decl->decl.linenum > 0 && decl->decl.filename != NULL)
  417.     {
  418.       xf1 = find_file (decl->decl.filename);
  419.       if (xf1 != NULL)
  420.     {
  421.       lineno = decl->decl.linenum;
  422.       xf = xf1;
  423.     }
  424.     }
  425.  
  426.   if (DECL_ASSEMBLER_NAME (decl))
  427.     name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
  428.   else
  429.     name = IDENTIFIER_POINTER (DECL_NAME (decl));
  430.  
  431.   strcpy (buf, type_as_string (TREE_TYPE (decl), 0));
  432.   simplify_type (buf);
  433.  
  434.   fprintf (xref_file, "DCL %s %d %s %d %s %s %s\n",
  435.        filename(xf), lineno, name,
  436.        (cur_scope != NULL ? cur_scope->lid : 0),
  437.        cls, fctname(fndecl), buf);
  438.  
  439.   if (STREQL (cls, "STRUCTID") || STREQL (cls, "UNIONID")
  440.       || STREQL (cls, "SIGNATUREID"))
  441.     {
  442.       cls = "CLASSID";
  443.       fprintf (xref_file, "DCL %s %d %s %d %s %s %s\n",
  444.            filename(xf), lineno,name,
  445.            (cur_scope != NULL ? cur_scope->lid : 0),
  446.            cls, fctname(fndecl), buf);
  447.     }
  448. }
  449.  
  450. /* Output a reference to a call to NAME in FNDECL.  */
  451.  
  452. void
  453. GNU_xref_call (fndecl, name)
  454.    tree fndecl;
  455.    char *name;
  456. {
  457.   XREF_FILE xf;
  458.   char buf[1024];
  459.   char *s;
  460.  
  461.   if (!doing_xref) return;
  462.   xf = find_file (input_filename);
  463.   if (xf == NULL) return;
  464.   name = fixname (name, buf);
  465.  
  466.   for (s = name; *s != 0; ++s)
  467.     if (*s == '_' && s[1] == '_') break;
  468.   if (*s != 0) GNU_xref_ref (fndecl, name);
  469.  
  470.   fprintf (xref_file, "CAL %s %d %s %s\n",
  471.        filename (xf), lineno, name, fctname (fndecl));
  472. }
  473.  
  474. /* Output cross-reference info about FNDECL.  If non-NULL,
  475.    ARGS are the arguments for the function (i.e., before the FUNCTION_DECL
  476.    has been fully built).  */
  477.  
  478. void
  479. GNU_xref_function (fndecl, args)
  480.    tree fndecl;
  481.    tree args;
  482. {
  483.   XREF_FILE xf;
  484.   int ct;
  485.   char buf[1024];
  486.  
  487.   if (!doing_xref) return;
  488.   xf = find_file (input_filename);
  489.   if (xf == NULL) return;
  490.  
  491.   ct = 0;
  492.   buf[0] = 0;
  493.   if (args == NULL) args = DECL_ARGUMENTS (fndecl);
  494.  
  495.   GNU_xref_decl (NULL, fndecl);
  496.  
  497.   for ( ; args != NULL; args = TREE_CHAIN (args))
  498.     {
  499.       GNU_xref_decl (fndecl,args);
  500.       if (ct != 0) strcat (buf,",");
  501.       strcat (buf, declname (args));
  502.       ++ct;
  503.     }
  504.  
  505.   fprintf (xref_file, "PRC %s %d %s %d %d %s\n",
  506.        filename(xf), lineno, declname(fndecl),
  507.        (cur_scope != NULL ? cur_scope->lid : 0),
  508.        ct, buf);
  509. }
  510.  
  511. /* Output cross-reference info about an assignment to NAME.  */
  512.  
  513. void
  514. GNU_xref_assign(name)
  515.    tree name;
  516. {
  517.   XREF_FILE xf;
  518.  
  519.   if (!doing_xref) return;
  520.   xf = find_file(input_filename);
  521.   if (xf == NULL) return;
  522.  
  523.   gen_assign(xf, name);
  524. }
  525.  
  526. static void
  527. gen_assign(xf, name)
  528.    XREF_FILE xf;
  529.    tree name;
  530. {
  531.   char *s;
  532.  
  533.   s = NULL;
  534.  
  535.   switch (TREE_CODE (name))
  536.     {
  537.     case IDENTIFIER_NODE :
  538.       s = IDENTIFIER_POINTER(name);
  539.       break;
  540.     case VAR_DECL :
  541.       s = declname(name);
  542.       break;
  543.     case COMPONENT_REF :
  544.       gen_assign(xf, TREE_OPERAND(name, 0));
  545.       gen_assign(xf, TREE_OPERAND(name, 1));
  546.       break;
  547.     case INDIRECT_REF :
  548.     case OFFSET_REF :
  549.     case ARRAY_REF :
  550.     case BUFFER_REF :
  551.       gen_assign(xf, TREE_OPERAND(name, 0));
  552.       break;
  553.     case COMPOUND_EXPR :
  554.       gen_assign(xf, TREE_OPERAND(name, 1));
  555.       break;
  556.       default :
  557.       break;
  558.     }
  559.  
  560.   if (s != NULL)
  561.     fprintf(xref_file, "ASG %s %d %s\n", filename(xf), lineno, s);
  562. }
  563.  
  564. /* Output cross-reference info about a class hierarchy.
  565.    CLS is the class type of interest.  BASE is a baseclass
  566.    for CLS.  PUB and VIRT give the access info about
  567.    the class derivation.  FRND is nonzero iff BASE is a friend
  568.    of CLS.
  569.  
  570.    ??? Needs to handle nested classes.  */
  571. void
  572. GNU_xref_hier(cls, base, pub, virt, frnd)
  573.    char *cls;
  574.    char *base;
  575.    int pub;
  576.    int virt;
  577.    int frnd;
  578. {
  579.   XREF_FILE xf;
  580.  
  581.   if (!doing_xref) return;
  582.   xf = find_file(input_filename);
  583.   if (xf == NULL) return;
  584.  
  585.   fprintf(xref_file, "HIE %s %d %s %s %d %d %d\n",
  586.       filename(xf), lineno, cls, base, pub, virt, frnd);
  587. }
  588.  
  589. /* Output cross-reference info about class members.  CLS
  590.    is the containing type; FLD is the class member.  */
  591.  
  592. void
  593. GNU_xref_member(cls, fld)
  594.    tree cls;
  595.    tree fld;
  596. {
  597.   XREF_FILE xf;
  598.   char *prot;
  599.   int confg, pure;
  600.   char *d;
  601.   int i;
  602.   char buf[1024], bufa[1024];
  603.  
  604.   if (!doing_xref) return;
  605.   xf = find_file(fld->decl.filename);
  606.   if (xf == NULL) return;
  607.  
  608.   if (TREE_PRIVATE (fld)) prot = "PRIVATE";
  609.   else if (TREE_PROTECTED(fld)) prot = "PROTECTED";
  610.   else prot = "PUBLIC";
  611.  
  612.   confg = 0;
  613.   if (TREE_CODE (fld) == FUNCTION_DECL && DECL_CONST_MEMFUNC_P(fld))
  614.     confg = 1;
  615.   else if (TREE_CODE (fld) == CONST_DECL)
  616.     confg = 1;
  617.  
  618.   pure = 0;
  619.   if (TREE_CODE (fld) == FUNCTION_DECL && DECL_ABSTRACT_VIRTUAL_P(fld))
  620.     pure = 1;
  621.  
  622.   d = IDENTIFIER_POINTER(cls);
  623.   sprintf(buf, "%d%s", strlen(d), d);
  624.   i = strlen(buf);
  625.   strcpy(bufa, declname(fld));
  626.  
  627. #ifdef XREF_SHORT_MEMBER_NAMES
  628.   for (p = &bufa[1]; *p != 0; ++p)
  629.     {
  630.       if (p[0] == '_' && p[1] == '_' && p[2] >= '0' && p[2] <= '9') {
  631.     if (strncmp(&p[2], buf, i) == 0) *p = 0;
  632.     break;
  633.       }
  634.       else if (p[0] == '_' && p[1] == '_' && p[2] == 'C' && p[3] >= '0' && p[3] <= '9') {
  635.     if (strncmp(&p[3], buf, i) == 0) *p = 0;
  636.     break;
  637.       }
  638.     }
  639. #endif
  640.  
  641.   fprintf(xref_file, "MEM %s %d %s %s %s %d %d %d %d %d %d %d\n",
  642.       filename(xf), fld->decl.linenum, d,  bufa,  prot,
  643.       (TREE_CODE (fld) == FUNCTION_DECL ? 0 : 1),
  644.       (DECL_INLINE (fld) ? 1 : 0),
  645.       (DECL_FRIEND_P(fld) ? 1 : 0),
  646.       (DECL_VINDEX(fld) ? 1 : 0),
  647.       (TREE_STATIC(fld) ? 1 : 0),
  648.       pure, confg);
  649. }
  650.  
  651. /* Find file entry given name.  */
  652.  
  653. static XREF_FILE
  654. find_file(name)
  655.    char *name;
  656. {
  657.   XREF_FILE xf;
  658.  
  659.   for (xf = all_files; xf != NULL; xf = xf->next) {
  660.     if (STREQL(name, xf->name)) break;
  661.   }
  662.  
  663.   return xf;
  664. }
  665.  
  666. /* Return filename for output purposes.  */
  667.  
  668. static char *
  669. filename(xf)
  670.    XREF_FILE xf;
  671. {
  672.   if (xf == NULL) {
  673.     last_file = NULL;
  674.     return "*";
  675.   }
  676.  
  677.   if (last_file == xf) return "*";
  678.  
  679.   last_file = xf;
  680.  
  681.   return xf->outname;
  682. }
  683.  
  684. /* Return function name for output purposes.  */
  685.  
  686. static char *
  687. fctname(fndecl)
  688.    tree fndecl;
  689. {
  690.   static char fctbuf[1024];
  691.   char *s;
  692.  
  693.   if (fndecl == NULL && last_fndecl == NULL) return "*";
  694.  
  695.   if (fndecl == NULL)
  696.     {
  697.       last_fndecl = NULL;
  698.       return "*TOP*";
  699.     }
  700.  
  701.   if (fndecl == last_fndecl) return "*";
  702.  
  703.   last_fndecl = fndecl;
  704.  
  705.   s = declname(fndecl);
  706.   s = fixname(s, fctbuf);
  707.  
  708.   return s;
  709. }
  710.  
  711. /* Return decl name for output purposes.  */
  712.  
  713. static char *
  714. declname(dcl)
  715.    tree dcl;
  716. {
  717.   if (DECL_NAME (dcl) == NULL) return "?";
  718.  
  719.   if (DECL_ASSEMBLER_NAME (dcl))
  720.     return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (dcl));
  721.   else
  722.     return IDENTIFIER_POINTER (DECL_NAME (dcl));
  723. }
  724.  
  725. /* Simplify a type string by removing unneeded parenthesis.  */
  726.  
  727. static void
  728. simplify_type(typ)
  729.    char *typ;
  730. {
  731.   char *s;
  732.   int lvl, i;
  733.  
  734.   i = strlen(typ);
  735.   while (i > 0 && isspace(typ[i-1])) typ[--i] = 0;
  736.  
  737.   if (i > 7 && STREQL(&typ[i-5], "const"))
  738.     {
  739.       typ[i-5] = 0;
  740.       i -= 5;
  741.     }
  742.  
  743.   if (typ[i-1] != ')') return;
  744.  
  745.   s = &typ[i-2];
  746.   lvl = 1;
  747.   while (*s != 0) {
  748.     if (*s == ')') ++lvl;
  749.     else if (*s == '(')
  750.       {
  751.     --lvl;
  752.     if (lvl == 0)
  753.       {
  754.         s[1] = ')';
  755.         s[2] = 0;
  756.         break;
  757.       }
  758.       }
  759.     --s;
  760.   }
  761.  
  762.   if (*s != 0 && s[-1] == ')')
  763.     {
  764.       --s;
  765.       --s;
  766.       if (*s == '(') s[2] = 0;
  767.       else if (*s == ':') {
  768.     while (*s != '(') --s;
  769.     s[1] = ')';
  770.     s[2] = 0;
  771.       }
  772.     }
  773. }
  774.  
  775. /* Fixup a function name (take care of embedded spaces).  */
  776.  
  777. static char *
  778. fixname(nam, buf)
  779.    char *nam;
  780.    char *buf;
  781. {
  782.   char *s, *t;
  783.   int fg;
  784.  
  785.   s = nam;
  786.   t = buf;
  787.   fg = 0;
  788.  
  789.   while (*s != 0)
  790.     {
  791.       if (*s == ' ')
  792.     {
  793.       *t++ = '\36';
  794.       ++fg;
  795.     }
  796.       else *t++ = *s;
  797.       ++s;
  798.     }
  799.   *t = 0;
  800.  
  801.   if (fg == 0) return nam;
  802.  
  803.   return buf;
  804. }
  805.  
  806. /* Open file for xrefing.  */
  807.  
  808. static void
  809. open_xref_file(file)
  810.    char *file;
  811. {
  812.   char *s, *t;
  813.  
  814. #ifdef XREF_FILE_NAME
  815.   XREF_FILE_NAME (xref_name, file);
  816. #else
  817.   s = rindex (file, '/');
  818.   if (s == NULL)
  819.     sprintf (xref_name, ".%s.gxref", file);
  820.   else
  821.     {
  822.       ++s;
  823.       strcpy (xref_name, file);
  824.       t = rindex (xref_name, '/');
  825.       ++t;
  826.       *t++ = '.';
  827.       strcpy (t, s);
  828.       strcat (t, ".gxref");
  829.     }
  830. #endif /* no XREF_FILE_NAME */
  831.  
  832.   xref_file = fopen(xref_name, "w");
  833.  
  834.   if (xref_file == NULL)
  835.     {
  836.       error("Can't create cross-reference file `%s'", xref_name);
  837.       doing_xref = 0;
  838.     }
  839. }
  840.